本篇繼續介紹 Query DSL的 Full text queries
本篇介紹以下 full text queries
query_string
query
query string 透過 "strict syntax(嚴格的語法)" 的parser來解析,
會先依據 operators 來 split(切分) query string, operators 像是 AND
, OR
, NOT
然後再一個一個 analyzes(分析) split text(切分的字串),之後才會去最匹配的動作
可以透過 query_string
來做到很複雜的搜尋,包含 使用wildcard 或 搜尋多個fields 等等,
但是 query是比較嚴格的,只要有無效的語法就會回傳錯誤,也因此官方也說明 query string
不建議拿來使用在 "search box(搜尋框)"
Example Request
GET /_search
{
"query": {
"query_string": {
"query": "(new york city) OR (big apple)", (1)
"default_field": "content" (2)
}
}
}
(1): 必填,欲用來搜尋的 query string
(2): 選填,如果 query string
沒有指定 field,就會使用此 default_field
的 field 來搜尋,如 default_field
也未提供,會使用index的設定 index.query.default_field
,而此設定預設是 *
, *
指的是所有fields中可支援 term
query 的fields
解析上述Request會如何parse
會把 query string
拆解成 new york city
和 big apple
兩部份,
而這兩部份一一被 content
field 的 analyzer 轉成 tokens,然後才去做匹配的動作
[指定fields]
此外,可以直接在 query string
中指定 用某一字串搜尋特定fields,
例如: status:active
搜尋 status
field 是否包含 active
title:(quick OR brown)
搜尋 title
field 是否包含 quick
或 brown
author:"John Smith"
搜尋 author
要包含 phrase "John Smith"
[範圍(range)]
range 可用在 date, numeric, string等等,其中使用
中括號 [min TO max]
代表有包含邊界值,使用大括號 {min TO max}
則不包含邊界值
例如: date:[2012-01-01 TO 2012-12-31]
搜尋 date
field 2012的每一天date:{* TO 2012-01-01}
搜尋 date
field 2012以前的所有日期(不包括2012-01-01)
也可以並用中大括號, count:[1 TO 5}
搜尋 count
field 數值1(包含) 至 5(不包含)
query_string
query 功能很複雜很多樣,但也比較嚴格,如上述所說,只要語法是無效的就會報錯,
官方文件也提及此query適合給 "專業使用者"
simple_query_string
query
query string 透過 "有限制可容錯" 的parser來解析,
根據 special operators 把 query string 切分成 terms,simple_query_string
不會因為無效的語法而報錯,他會忽略他
Example Request
GET /_search
{
"query": {
"simple_query_string" : {
"query": "\"fried eggs\" +(eggplant | potato) -frittata", (1)
"fields": ["title^5", "body"], (2)
"default_operator": "and" (3)
}
}
}
(1): 必填,即 query string
(2): 選填,欲搜尋的 fields (可多個), 其中 ^5
,代表著 title
權重是 body
的5倍
(3): 選填,在 query string
中,如果沒有指定 operators ,則會使用此 default_operator
設定的operator, default_operator
可填的值有 OR
和 AND
, default_operator
預設值為 OR
simple_query_string
支援的operators有:
+
代表 AND
動作|
代表 OR
動作-
代表 NOT
否定"
包起來的字串代表要 phrase
query*
放在term之後代表 prefix
query(
and )
表示優先度較高~N
放在字詞之後代表 edit distance (fuzziness)~N
放在 phrase 之後 代表 slop amount不過上述的operators是可以透過參數 flags
來限制,預設此參數的值為 ALL
,也就是這些 operators預設都支援
其實 default_operator
參數影響很大,舉個例子
GET /_search
{
"query": {
"simple_query_string": {
"fields": [ "content" ],
"query": "foo bar -baz"
}
}
}
原本的意圖是希望找出 content
field 含有 foo
或 bar
,但是不含 baz
,
但因為 default_operator
是 OR
,
所以實際上解析出來是,搜尋 content
field 含有 foo
或 bar
或 任何不含baz
,
也就是說 含有 baz
的documents也會被匹配得到,
那要怎麼達到原本意圖呢?
query string 改成 "foo bar +-baz" 即可,
代表著 欲搜尋 content
field 含有 foo
或 bar
"且" 不含baz
,
官方文件有說明到,此 simple_query_string
query 比 query_string
還要 "穩健(robust)",
適合直接拿來對外給使用者使用
intervals
query
對於 matching terms 的組合,可以做到很細微的排序以及位置接近程度的控制
是由 matching rules 組成,最後組成的rules套用在指定的 field
支援的rules有:
以 match
rule為例,提供了參數 max_gaps
控制匹配的terms之間可接受的最大的位置距離,
也提供了參數 ordered
設定匹配的terms的順序是否要和 query string中的位置順序一樣
intervals
query 可以用到很精細微小,若有興趣深究可參考reference
common
terms query
是個比較"專門"用來搜不常見的詞的query
不過因為在 es 7.3.0 被棄用了,且官方文件建議直接使用 match
所以在這就不多做介紹了
小小新手,如有理解錯誤或寫錯再請不吝提醒或糾正
Full text queries
query string syntax
Intervals query